from tkinter import *
from tkinter.ttk import *
import tkinter.messagebox as messageBox
# import tkinter.tix
import time
import re

from ...utils.loggers import dev_logger, prod_logger, record_logger
from ...utils.utils import singleton
# FIXME: 通过.模式，相对引入方式
from ..yuanchengqidong.window import  app_window 
from ..master_window import GcanViewTemplate


@singleton
class SeatTest:
    def __init__(self, master:GcanViewTemplate) -> None:
        # 全局master实例
        self.MASTER = master

        # 初始操作主窗口
        self.initMaster()
        # 当前窗口实例
        self.initCurWindow()
        
    def initMaster(self):
        self.MASTER.caninit()
        self.MASTER.withdraw()

    def initCurWindow(self):
        self.curWindow = Toplevel(self.MASTER)
        self.curWindow.geometry('900x600+600+200')
        self.curWindow.title('座椅测试操作台')

        self.initUserWindowFrame1()
        self.initUserWindowFrame2()
        self.initUserWindowFrame3()
        self.initUserWindowFrame8()
        self.initUserWindowFrame6()


        # 启动程序时让vin码输入框自动获取焦点
        self.curVinCodeEntry.focus_set()
        pass

    def initUserWindowFrame1(self):
        '''
            VIN 输入框Frame
        '''

        # 本地函数
        if 1:
            # [x]: 后期改为扫码获取值,与OBD读取值得比对
            def validateVinCode():
                # Vin码输入框验证函数
                curVin = self.curVinCode.get()
                # print(f'validate VinCode {curVin}')

                # [x]: 待开启VIN匹配功能
                pat = re.compile(r'^LNB\w{8}\d{6}$')
                if pat.match(curVin):
                # if len(curVin) > 4:

                    self.userWindowFrame2_1Btn1.configure(state='normal')
                    self.userWindowFrame2_1Btn2.configure(state='normal')
                    self.userWindowFrame2_1Btn3.configure(state='normal')
                    self.userWindowFrame2_1Btn4.configure(state='normal')
                    self.userWindowFrame2_1Btn5.configure(state='normal')
                    self.userWindowFrame2_1Btn6.configure(state='normal')
                    self.userWindowFrame2_1Btn7.configure(state='normal')
                    self.userWindowFrame2_1Btn8.configure(state='normal')

                    self.userWindowFrame3_Btn1.configure(state='normal')
                    self.userWindowFrame3_Btn2.configure(state='normal')
                    self.userWindowFrame3_Btn3.configure(state='normal')
                    return True
                    
                else:
                    return False

            def validateVinCodeFailed():
                self.userWindowFrame2_1Btn1.configure(state='disabled')
                self.userWindowFrame2_1Btn2.configure(state='disabled')
                self.userWindowFrame2_1Btn3.configure(state='disabled')
                self.userWindowFrame2_1Btn4.configure(state='disabled')
                self.userWindowFrame2_1Btn5.configure(state='disabled')
                self.userWindowFrame2_1Btn6.configure(state='disabled')
                self.userWindowFrame2_1Btn7.configure(state='disabled')
                self.userWindowFrame2_1Btn8.configure(state='disabled')

                messageBox.showwarning('VIN码验证警告','VIN码验证不通过，请核对输入的VIN码是否正确？')
                # print('validate failed...')
                pass

            def curVinCodeEntryReset():
                # 清理输入框内容，获取焦点
                    self.curVinCodeEntry.delete(0,END)
                    self.curVinCodeEntry.focus_set()
                    
                    # 设置按钮使能
                    # TODO: 后期将几个测试按钮的使能操作打包起来,或者用容器装起来,遍历实现可扩展性.
                    self.userWindowFrame2_1Btn1.configure(state='disabled')
                    self.userWindowFrame2_1Btn2.configure(state='disabled')
                    self.userWindowFrame2_1Btn3.configure(state='disabled')
                    self.userWindowFrame2_1Btn4.configure(state='disabled')
                    self.userWindowFrame2_1Btn5.configure(state='disabled')
                    self.userWindowFrame2_1Btn6.configure(state='disabled')
                    self.userWindowFrame2_1Btn7.configure(state='disabled')
                    self.userWindowFrame2_1Btn8.configure(state='disabled')
                    
                    self.userWindowFrame3_Btn1.configure(state='disabled')
                    self.userWindowFrame3_Btn2.configure(state='disabled')
                    self.userWindowFrame3_Btn3.configure(state='disabled')

                    # [ ] 待确认,重置后是否把展示状态复位?
                    for wediget in self.userWindowFrame2_1TestResMsg.values():
                        print('wdiget:', wediget)
                        wediget.configure(text='待检测...', foreground='gray')
                        # wediget.configure(foreground='gray')


        self.userWindowFrame1 = Frame(self.curWindow, relief='groove')
        self.userWindowFrame1.grid(row=1, column=1,columnspan=5, padx=20, pady=20)
        self.curVinCodeLabel = Label(self.userWindowFrame1, text='输入当前VIN码')
        self.curVinCodeLabel.grid(row=1, column=1, padx=10, pady=10)
        self.curVinCode = StringVar()
        self.curVinCode.set('LNB12341234123412')
        self.curVinCodeEntry = Entry(self.userWindowFrame1, textvariable=self.curVinCode,validate='focusout', validatecommand=validateVinCode, invalidcommand=validateVinCodeFailed)
        self.curVinCodeEntry.grid(row=1, column=2, padx=10, pady=10)
        self.curVinCodeConfirmBtn = Button(self.userWindowFrame1, text='确认')
        self.curVinCodeConfirmBtn.grid(row=1, column=3, padx=10, pady=10)
        self.curVinCodeResetBtn = Button(self.userWindowFrame1, text='重置', command=curVinCodeEntryReset)
        self.curVinCodeResetBtn.grid(row=1, column=4, padx=10, pady=10)

    def initUserWindowFrame2(self):
        '''
            单个座椅测量按钮
        '''
        self.userWindowFrame2 = Frame(self.curWindow)
        self.userWindowFrame2.grid(row=2, column=1,columnspan=5, padx=20, pady=20)
        if 1:
            self.userWindowFrame2_1 = Frame(self.userWindowFrame2, relief='groove')
            self.userWindowFrame2_1.grid(row=1, column=1)
            # TODO: 后期改成遍历循环模式
            if 1:
                self.userWindowFrame2_1TestResMsg ={}
                self.userWindowFrame2_1Btn1 = Button(self.userWindowFrame2_1,state=DISABLED,text='主驾按摩',command=self.seatUnittest('00'))
                self.userWindowFrame2_1Btn1.grid(row=1,column=1,padx=10,pady=10)
                self.userWindowFrame2_1TestResMsg['00'] = Message(self.userWindowFrame2_1,width=200,foreground='gray',text='主驾按摩测试结果')
                self.userWindowFrame2_1TestResMsg['00'].grid(row=1, column=2,padx=10, pady=10)
                self.userWindowFrame2_1Btn2 = Button(self.userWindowFrame2_1,state=DISABLED,text='副驾按摩',command=self.seatUnittest('01'))
                self.userWindowFrame2_1Btn2.grid(row=1,column=3,padx=10, pady=10)
                self.userWindowFrame2_1TestResMsg['01'] = Message(self.userWindowFrame2_1,width=200,foreground='gray',text='副驾按摩测试结果')
                self.userWindowFrame2_1TestResMsg['01'].grid(row=1, column=4,padx=10, pady=10)
                self.userWindowFrame2_1Btn3 = Button(self.userWindowFrame2_1,state=DISABLED,text='左后按摩',command=self.seatUnittest('02'))
                self.userWindowFrame2_1Btn3.grid(row=2,column=1,padx=10,pady=10)
                self.userWindowFrame2_1TestResMsg['02'] = Message(self.userWindowFrame2_1,width=200,foreground='gray',text='左后按摩测试结果')
                self.userWindowFrame2_1TestResMsg['02'].grid(row=2, column=2,padx=10, pady=10)
                self.userWindowFrame2_1Btn4 = Button(self.userWindowFrame2_1,state=DISABLED,text='右后按摩',command=self.seatUnittest('03'))
                self.userWindowFrame2_1Btn4.grid(row=2,column=3,padx=10, pady=10)
                self.userWindowFrame2_1TestResMsg['03'] = Message(self.userWindowFrame2_1,width=200,foreground='gray',text='右后按摩测试结果')
                self.userWindowFrame2_1TestResMsg['03'].grid(row=2, column=4,padx=10, pady=10)

                self.userWindowFrame2_1Btn5 = Button(self.userWindowFrame2_1,state=DISABLED,text='主驾通风加热',command=self.seatUnittest('10'))
                self.userWindowFrame2_1Btn5.grid(row=3,column=1,padx=10,pady=10)
                self.userWindowFrame2_1TestResMsg['10'] = Message(self.userWindowFrame2_1,width=200,foreground='gray',text='主驾通风加热测试结果')
                self.userWindowFrame2_1TestResMsg['10'].grid(row=3, column=2,padx=10, pady=10)


                self.userWindowFrame2_1Btn6 = Button(self.userWindowFrame2_1,state=DISABLED,text='副驾通风加热',command=self.seatUnittest('11'))
                self.userWindowFrame2_1Btn6.grid(row=3,column=3,padx=10, pady=10)
                self.userWindowFrame2_1TestResMsg['11'] = Message(self.userWindowFrame2_1,width=200,foreground='gray',text='副驾通风加热测试结果')
                self.userWindowFrame2_1TestResMsg['11'].grid(row=3, column=4,padx=10, pady=10)

                self.userWindowFrame2_1Btn7 = Button(self.userWindowFrame2_1,state=DISABLED,text='左后通风加热',command=self.seatUnittest('12'))
                self.userWindowFrame2_1Btn7.grid(row=4,column=1,padx=10,pady=10)
                self.userWindowFrame2_1TestResMsg['12'] = Message(self.userWindowFrame2_1,width=200,foreground='gray',text='左后通风加热测试结果')
                self.userWindowFrame2_1TestResMsg['12'].grid(row=4, column=2,padx=10, pady=10)


                self.userWindowFrame2_1Btn8 = Button(self.userWindowFrame2_1,state=DISABLED,text='右后通风加热',command=self.seatUnittest('13'))
                self.userWindowFrame2_1Btn8.grid(row=4,column=3,padx=10, pady=10)
                self.userWindowFrame2_1TestResMsg['13'] = Message(self.userWindowFrame2_1,width=200,foreground='gray',text='右后通风加热测试结果')
                self.userWindowFrame2_1TestResMsg['13'].grid(row=4, column=4,padx=10, pady=10)

    def initUserWindowFrame3(self):
        '''
            一键快检Frame
        '''

        # 增加一键快检功能
        self.userWindowFrame3 = Frame(self.curWindow, relief='groove')
        self.userWindowFrame3.grid(row=3, column=1,columnspan=5, padx=20, pady=20)


        # 本地函数
        if 1:
            # FIXME: 一键快检功能函数
            # [ ] 待确认几个按钮同时点击会否有异步运行问题
            def testLV3():
                self.userWindowFrame2_1Btn1.invoke()
                self.userWindowFrame2_1Btn2.invoke()

                self.userWindowFrame2_1Btn5.invoke()
                self.userWindowFrame2_1Btn6.invoke()
            
            def testLV4():
                self.userWindowFrame2_1Btn1.invoke()
                self.userWindowFrame2_1Btn2.invoke()
                self.userWindowFrame2_1Btn3.invoke()
                self.userWindowFrame2_1Btn4.invoke()

                self.userWindowFrame2_1Btn5.invoke()
                self.userWindowFrame2_1Btn6.invoke()
                self.userWindowFrame2_1Btn7.invoke()
                self.userWindowFrame2_1Btn8.invoke()
            
            def testLV5():
                '''
                    与LV4相同,所以直接调用LV4的test
                '''
                testLV4()


        # 按钮布局
        if 1:
            self.userWindowFrame3_Label1 = Label(self.userWindowFrame3, text='一键快检')
            self.userWindowFrame3_Label1.grid(row=1, column=1,columnspan=3, padx=20, pady=20)
            self.userWindowFrame3_Btn1 = Button(self.userWindowFrame3, state=DISABLED, text='LV3', command=testLV3)
            self.userWindowFrame3_Btn1.grid(row=2, column=1, padx=20, pady=20)
            self.userWindowFrame3_Btn2 = Button(self.userWindowFrame3,state=DISABLED, text='LV4', command=testLV4)
            self.userWindowFrame3_Btn2.grid(row=2, column=2, padx=20, pady=20)
            self.userWindowFrame3_Btn3 = Button(self.userWindowFrame3, state=DISABLED, text='LV5', command=testLV5)
            self.userWindowFrame3_Btn3.grid(row=2, column=3, padx=20, pady=20)

    def initUserWindowFrame8(self):
        '''
            显示主窗口 
        '''

        self.userWindowFrame8 = Frame(self.curWindow, relief='groove')
        self.userWindowFrame8.grid(row=3, column=5, padx=20, pady=20)
        if 1:
            self.userWindowFrame8Btn1 = Button(self.userWindowFrame8, text='显示主窗口',command=self.MASTER.deiconify)
            self.userWindowFrame8Btn1.grid(row=1, column=1, padx=10, pady=10)

        if 1:
            self.userWindowFrame7Btn1 = Button(self.userWindowFrame8, text='远程启动测试', command=self.remoteStartTest)
            self.userWindowFrame7Btn1.grid(row=2, column=1, padx=10, pady=10)

    def remoteStartTest(self):
        '''
            远程启动测试
        '''
        app_window(self.MASTER)
        pass

    def initUserWindowFrame6(self):
        '''
            运行信息展示
        '''

        # 测试结果显示框
        self.userWindowFrame6 = Frame(self.curWindow)
        self.userWindowFrame6.grid(row=6,column=1,columnspan=5, padx=20,pady=20)
        if 1:

            self.userWindowFrame6recordListboxScroll = Scrollbar(self.userWindowFrame6, orient=VERTICAL)
            self.userWindowFrame6recordListboxScroll.grid(row=2, column=11, sticky="ns")
            self.userWindowFrame6recordListbox = Listbox(
                self.userWindowFrame6,
                font=("Arial", 12),
                height=10,
                width=80,
                yscrollcommand=self.userWindowFrame6recordListboxScroll.set,
            )
            self.userWindowFrame6recordListbox.grid(row=2, column=0, columnspan=11, sticky="nw")
            self.userWindowFrame6recordListboxScroll.config(command=self.userWindowFrame6recordListbox.yview)
            self.userWindowFrame6recordClearBtn = Button(
                self.userWindowFrame6,
                text="清空测试记录",
                command=lambda: self.userWindowFrame6recordListbox.delete(0,END),
            )
            self.userWindowFrame6recordClearBtn.grid(row=2, column=12, padx=2, pady=1)

    def seatUnittest(self, posId):
        # dev_logger.debug(f'seatUnittest running...{posId}.........')
        unitName = self.MASTER.TESTCONFIGDATADICT[posId].name
        dev_logger.debug(f'seatUnittest running...{posId}....unitName:{unitName}.....')

        def callback(worker):
            # dev_logger.debug(f'seatUnittest  callback running ...{posId}.........')
            resFlag, resString, result = worker.result()
            dev_logger.debug(f'seatUnittest  callback running ...{posId}...{resFlag, resString}.........')

            # userwindow中的信息展示
            self.userWindowFrame2_1TestResMsg[posId].configure(text=resString)
            foreground = 'green' if resFlag else 'red'
            self.userWindowFrame2_1TestResMsg[posId].configure(foreground=foreground)

            # 保留测试record信息
            recordStringLogger = f'VIN,{self.curVinCode.get():>17},{resString}' 
            record_logger.info(recordStringLogger)

            # 增加当前时间
            recordStringListobx = f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}--{unitName}---{recordStringLogger}'
            # print('----',recordStr)
            self.userWindowFrame6recordListbox.insert('end', recordStringListobx)
            # 设置条目颜色
            if not resFlag:
                self.userWindowFrame6recordListbox.itemconfig('end', background='pink')
            self.userWindowFrame6recordListbox.see(self.userWindowFrame6recordListbox.size())
            # pass
        
        def wrapper():
            dev_logger.debug(f'seatUnittest  wrapper running ...{posId}.........')
            # res = self.pool.submit(inner)
            # testResult 其实是一个上面的线程池任务返回对象,异步任务的返回值
            # 点击按钮的测试结果结构是 resFlag,resString
            testResult = self.MASTER.unitTestCommand(posId)()
            testResult.add_done_callback(callback)

        return wrapper


def app_window(master):
    '''
        座椅检测弹出窗口
    '''
    SeatTest(master)

